package com.genentech.bioinformatics.mobi;
/*
 * Class by Jeff Milton, except where otherwise noted.
 */
import java.util.ArrayList;
import java.util.Date;

import com.genentech.flexigraph.Grid;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.ImageView;

public class AnnotatePanel extends SurfaceView implements
		SurfaceHolder.Callback {
	private ArrayList<Path> _graphics = new ArrayList<Path>();
	private Paint mPaint;
	private Paint fPaint;
	private DrawingThread _thread;
	private Path path;
	private Point my_point = new Point(0, 0);
	private GestureDetector gestureDetector = null;
	private Grid grid = new Grid(0, 0, 200, 200);
	private boolean ready_to_draw = false;
	private ArrayList<GANnotation> ats = new ArrayList<GANnotation>();
	private TermGraph left = new TermGraph();
	private TermGraph right = new TermGraph();

	public AnnotatePanel(Context context, AttributeSet _set) {
		super(context, _set);
		_thread = new DrawingThread(getHolder(), this);
		buildPaintObject();
		getHolder().addCallback(this);
		
		// build the left
		Grid tgrid = new Grid ();
		tgrid.setxmax(5f);
		tgrid.setymax(10f);
		tgrid.setxmin(0f);
		tgrid.setymin(0f);
		tgrid.setXi(0);
		tgrid.setYi(1);
		tgrid.setWidth(4);
		tgrid.setHeight(9);
		left.setGrid(tgrid);
		// build the rigth
		Grid rgrid = new Grid ();
		rgrid.setxmax(5f);
		rgrid.setymax(10f);
		rgrid.setxmin(6f);
		rgrid.setymin(0f);
		rgrid.setXi(6);
		rgrid.setYi(1);
		rgrid.setWidth(4);
		rgrid.setHeight(2);
		right.setGrid(rgrid);

		GridIndex.addGrid("background", grid);
		GridIndex.addTermGraph("left", left);
		GridIndex.addTermGraph("right", right);
		// Bitmap test_image = BitmapFactory.decodeResource(
		// context.getResources(), R.drawable.ball);
		// backdrop = BitmapFactory.decodeResource(context.getResources(),
		// R.drawable.default);
		gestureDetector = new GestureDetector(
				new AnnotateGestureDetection(this));
		buildTestAnnotations();
	}

	private void buildTestAnnotations() {
		GANnotation t = new GANnotation(Color.GREEN, 5, 11);
		ats.add(t);
		GANnotation t1 = new GANnotation(Color.CYAN, 1, 1);
		ats.add(t1);
		GANnotation t2 = new GANnotation(Color.DKGRAY, 9, 2);
		ats.add(t2);
		GANnotation t3 = new GANnotation(Color.LTGRAY, 7, 5);
		ats.add(t3);

		for (int i = 0; i < 200; i += 2) {
			GANnotation tt = new GANnotation(Color.WHITE, 8, i);
			ats.add(tt);
		}
	}

	private void buildPaintObject() {
		grid.setXi(0);
		grid.setYi(0);
		grid.setxmax(10f);
		grid.setxmin(0.0f);
		grid.setymax(10f);
		grid.setymin(0.0f);
		mPaint = new Paint();
		mPaint.setDither(true);
//		mPaint.setColor(0xFFFFFF00);
		mPaint.setColor(Color.DKGRAY);
		mPaint.setStyle(Paint.Style.STROKE);
		mPaint.setStrokeJoin(Paint.Join.ROUND);
		mPaint.setStrokeCap(Paint.Cap.ROUND);
		mPaint.setStrokeWidth(2);
		fPaint = new Paint();
		// fPaint.setDither(true);
		fPaint.setColor(Color.WHITE);
		// fPaint.setStyle(Paint.Style.STROKE);
		// fPaint.setStrokeJoin(Paint.Join.ROUND);
		// fPaint.setStrokeCap(Paint.Cap.ROUND);
		fPaint.setStrokeWidth(1);
	}

	public boolean onTouchEvent(MotionEvent event) {
		synchronized (_thread.getSurfaceHolder()) {
			my_point.set((int) event.getX(), (int) event.getY());
			if (gestureDetector.onTouchEvent(event)) {
				return true;
			} else {
				if (event.getAction() == MotionEvent.ACTION_DOWN) {
					path = new Path();
					path.moveTo(event.getX(), event.getY());
					path.lineTo(event.getX(), event.getY());
					float x = grid.Xwc((int) event.getX());
					float y = grid.Ywc((int) event.getY());
					for (GANnotation gg : ats) {
						if (gg.isInside(x, y)) {
							gg.select();
						}
					}
				} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
					path.lineTo(event.getX(), event.getY());
					float x = grid.Xwc((int) event.getX());
					float y = grid.Ywc((int) event.getY());
					for (GANnotation gg : ats) {
						if (gg.isInside(x, y)) {
							gg.highlight();
						}
					}
				} else if (event.getAction() == MotionEvent.ACTION_UP) {
					TermGraph g = GridIndex.getTermGraph(event.getX(), event.getY());
					if( g != null )
					{
						
					}

					
					
					path.lineTo(event.getX(), event.getY());
					_graphics.add(path);
					float x = grid.Xwc((int) event.getX());
					float y = grid.Ywc((int) event.getY());
					for (GANnotation gg : ats) {
						if (gg.isInside(x, y)) {
							gg.unhighlight();
						}
					}
				}
			}
			return true;
		}
	}

	public void onDraw(Canvas canvas) {
		canvas.drawColor(Color.BLACK);
		grid.setWidth(canvas.getWidth());
		grid.setHeight(canvas.getHeight());
		grid.rescale();
		int xincrement = 1;
		int yincrement = 1;
		// draw the grid
		if (mPaint != null) {
			canvas.drawRect(grid.getXi(), grid.getYi(), grid.getWidth(),
					grid.getHeight(), mPaint);
			for (float x = grid.getxmin(); x < grid.getxmax(); x += xincrement) {
				for (float y = grid.getymin(); y < grid.getymax(); y += yincrement) {
					Path _path = new Path();
					_path.moveTo(grid.X(grid.getxmin()), grid.Y(y));
					_path.lineTo(grid.X(grid.getxmax()), grid.Y(y));
					canvas.drawPath(_path, mPaint);
					canvas.drawText("" + y, grid.X(grid.getxmin()) - 15,
							grid.Y(y), fPaint);
				}
			}
			for (float y = grid.getymin(); y < grid.getymax(); y += yincrement) {
				for (float x = grid.getxmin(); x < grid.getxmax(); x += xincrement) {
					Path _path = new Path();
					_path.moveTo(grid.X(x), grid.Y(grid.getymin()));
					_path.lineTo(grid.X(x), grid.Y(grid.getymax()));
					canvas.drawPath(_path, mPaint);
					canvas.drawText("" + x, grid.X(x),
							5 + grid.Y(grid.getymin()), fPaint);
				}
			}
		}
		for (GANnotation gg : ats) {
			gg.draw(canvas, grid);
		}
		if (left != null)
			left.draw(canvas, grid);

		if (right != null)
			right.draw(canvas, grid);

		// if (backdrop != null)
		// canvas.drawBitmap(backdrop, 0, 0, mPaint);
		if (path != null && mPaint != null)
			canvas.drawPath(path, mPaint);
		// for (Path path : _graphics) {
		// // canvas.drawPoint(graphic.x, graphic.y, mPaint);
		// canvas.drawPath(path, mPaint);
		// }

	}

	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {

	}

	public void surfaceCreated(SurfaceHolder holder) {
		ready_to_draw = true;
		_thread.setRunning(true);
		_thread.start();
		// final Thread thrd = new Thread() {
		// public void run() {
		// try {
		// sleep(1000);
		// } catch (Exception _e) {
		// } finally {
		// }
		// }
		// };
		// thrd.start();
	}

	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		boolean retry = true;
		_thread.setRunning(false);
		while (retry) {
			try {
				_thread.join();
				retry = false;
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	public void up(int dist, Grid g) {
		// float r = 0.5f;
		// float incr = (((grid.getymax() - grid.getymin()) / 2) * (r));
		// grid.setymax(grid.getymax() + incr);
		// grid.setymin(grid.getymin() + incr);

		float incr = g.worldHeight(dist);
		// (((grid.getymax() - grid.getymin()) / 2) * (r));

		g.setymax(g.getymax() - incr);
		g.setymin(g.getymin() - incr);
	}

	public void down(int dist, Grid g) {
		float incr = g.worldHeight(dist);
		// (((g.getymax() - g.getymin()) / 2) * (r));

		g.setymax(g.getymax() - incr);
		g.setymin(g.getymin() - incr);
	}

	public boolean readyToDraw() {
		return ready_to_draw;
	}
}

class DrawingThread extends Thread {
	private SurfaceHolder _surfaceHolder;
	private AnnotatePanel _panel;
	private boolean _run = false;

	public DrawingThread(SurfaceHolder surfaceHolder, AnnotatePanel panel) {
		_surfaceHolder = surfaceHolder;
		_panel = panel;
	}

	public void setRunning(boolean run) {
		_run = run;
	}

	public SurfaceHolder getSurfaceHolder() {
		return _surfaceHolder;
	}

	static int draw = 0;
	static int canvas = 0;

	public void run() {
		Canvas c;
		while (_run) {
			c = null;
			try {
				c = _surfaceHolder.lockCanvas();
				synchronized (_surfaceHolder) {
					// Log.println(MAX_PRIORITY, "ftse", "draw: " + draw++);
					_panel.onDraw(c);
				}
			} finally {
				// do this in a finally so that if an exception is thrown
				// during the above, we don't leave the Surface in an
				// inconsistent state
				if (c != null) {
					// System.out.println("draw canvas: " + canvas++);
					_surfaceHolder.unlockCanvasAndPost(c);
				}
			}
			try {
				sleep(500);
			} catch (Exception _e) {
				_e.printStackTrace();
			}
			// // Reschedule the next redraw.
			// _panel.getHandler().removeCallbacks(this);
			// // Play around with the delay for an optimal result.
			// _panel.getHandler().postDelayed(this, 25);

		}
	}
}
